package com.huawei.ceiling;

import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ComponentParent;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ListContainer;
import ohos.agp.components.StackLayout;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

public class BaseProvider extends BaseItemProvider {
    protected BaseItemProvider myProvider;
    protected Context context;
    protected List<StickyBean> providerList;
    protected int layoutId;
    protected ComponentBindingListener componentBindingListener;

    private ListContainer upListContainer;
    private ListContainer downListContainer;
    int upContainerScrollY;
    protected StickyListener stickyListener;

    public BaseProvider(Context context, int layoutId) {
        this.context = context;
        this.layoutId = layoutId;
        myProvider = this;
    }

    public BaseProvider(Context context, List<StickyBean> providerList, int layoutId) {
        this(context, layoutId);
        this.providerList = providerList;
    }

    public BaseProvider(Context context, ListContainer listContainer, List providerList, int layoutId) {
        this(context, providerList, layoutId);
        handleList(listContainer);
    }

    @Override
    public int getCount() {
        return providerList == null ? 0 : providerList.size();
    }

    @Override
    public Object getItem(int position) {
        return Optional.of(providerList.get(position));
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemComponentType(int position) {
        return super.getItemComponentType(position);
    }

    @Override
    public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
        StickyViewHolder viewHolder = null;
        if (component != null) viewHolder = (StickyViewHolder) component.getTag();

        if (viewHolder == null) {
            component = LayoutScatter.getInstance(context).parse(layoutId, null, false);
            if (componentBindingListener != null) {
                viewHolder = componentBindingListener.creatViewHolder(component);
            } else {
                viewHolder = new StickyViewHolder(component);
            }
            component = viewHolder.itemView;
            component.setTag(viewHolder);
        }

        if (viewHolder != null && componentBindingListener != null) {
            componentBindingListener.initData(viewHolder, providerList.get(position), position);
        }
        return component;
    }

    public void setComponentBindingListener(ComponentBindingListener listener) {
        componentBindingListener = listener;
    }

    //--------------吸顶效果
    public void setStickyListener(StickyListener stickyListener) {
        this.stickyListener = stickyListener;
    }

    public void handleList(ListContainer listContainer) {
        this.downListContainer = listContainer;
        if (listContainer == null) return;
        StackLayout stackLayout = new StackLayout(listContainer.getContext());
        stackLayout.setLayoutConfig(listContainer.getLayoutConfig());
        upListContainer = new ListContainer(listContainer.getContext());
        upListContainer.setEnabled(false);
        listContainer.setLayoutRefreshedListener(component -> {
            ComponentContainer.LayoutConfig layoutConfig = upListContainer.getLayoutConfig();
            //获取第一个Head的索引
            int visibleStartIndex = downListContainer.getItemPosByVisibleIndex(0);
            int i = visibleStartIndex;
            for (; i < visibleStartIndex + downListContainer.getVisibleIndexCount(); i++) {
                if (stickyListener != null && !stickyListener.isStickyItemHide(providerList.get(i))) break;
            }
            if (i == visibleStartIndex + downListContainer.getVisibleIndexCount()) return;

            Component tmp = listContainer.getComponentAt(i);
            if (layoutConfig.width != tmp.getWidth() || layoutConfig.height != tmp.getHeight()) {
                upListContainer.setLayoutConfig(new ComponentContainer.LayoutConfig(
                        tmp.getWidth(), tmp.getHeight()));
                itemChange();
            }
        });

        ComponentParent componentParent = listContainer.getComponentParent();
        int index = componentParent.getChildIndex(listContainer);
        componentParent.removeComponent(listContainer);
        ((ComponentContainer) componentParent).addComponent(stackLayout, index);

        stackLayout.addComponent(listContainer);
        stackLayout.addComponent(upListContainer);

        listContainer.addScrolledListener((component, i, i1, i2, i3) -> {
            if (isUpScroll()) {
                upContainerScrollY = upContainerScrollY + i1 - i3;
                upListContainer.scrollTo(0, upContainerScrollY);
            } else {
                upContainerHoming();
            }
        });
    }

    public void itemChange() {
        if (stickyListener == null) return;

        List<StickyBean> tmpList = new ArrayList<>(providerList);
        Iterator it = tmpList.iterator();
        while (it.hasNext()) {
            if (stickyListener.isStickyItemHide(it.next())) {
                it.remove();
            }
        }

        BaseProvider provider = new BaseProvider(context, null, tmpList, layoutId);
        provider.setComponentBindingListener(new ComponentBindingListener() {
            @Override
            public StickyViewHolder creatViewHolder(Component item) {
                if (componentBindingListener == null)
                    return new StickyViewHolder(item);
                else
                    return componentBindingListener.creatViewHolder(item);
            }

            @Override
            public void initData(StickyViewHolder viewHolder, StickyBean object, int position) {
                if (componentBindingListener != null)
                    componentBindingListener.initData(viewHolder, object, position);
            }
        });
        upListContainer.setItemProvider(provider);
    }

    public boolean isUpScroll() {
        float upContainerHeight = upListContainer.getHeight();

        int visibleStartIndex = downListContainer.getItemPosByVisibleIndex(0);
        for (int i = visibleStartIndex; i < visibleStartIndex + downListContainer.getVisibleIndexCount(); i++) {
            if (stickyListener != null && !stickyListener.isStickyItemHide(providerList.get(i))) {
                float downHeadTopY = downListContainer.getComponentAt(i).getContentPositionY();
                if (upContainerHeight >= downHeadTopY && downHeadTopY > 0) return true;
            }
        }
        return false;
    }

    //顶部Container滑动完后，进行归位
    public void upContainerHoming() {
        int downIndex = downListContainer.getItemPosByVisibleIndex(0);
        int downHeadIndex = -1;
        for (int i = 0; i <= downIndex; i++) {
            if (stickyListener != null && !stickyListener.isStickyItemHide(providerList.get(i))) {
                downHeadIndex++;
            }
        }

        if (downHeadIndex == -1) downHeadIndex = 0;

        //顶部Container进行对齐
        upListContainer.getItemProvider().notifyDataChanged();
        upContainerScrollY = downHeadIndex * upListContainer.getHeight();
        upListContainer.scrollTo(0, upContainerScrollY);
    }

    public interface ComponentBindingListener {
        StickyViewHolder creatViewHolder(Component item);

        void initData(StickyViewHolder viewHolder, StickyBean object, int position);
    }

    public interface StickyListener {
        boolean isStickyItemHide(Object object);
    }
}